package com.xianyun.book.gatewayimpl.elasticsearch.repository.base;

import com.xianyun.book.gatewayimpl.elasticsearch.dataobject.SupportEsDO;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.search.suggest.Suggest;
import org.elasticsearch.search.suggest.SuggestBuilder;
import org.elasticsearch.search.suggest.SuggestBuilders;
import org.elasticsearch.search.suggest.completion.CompletionSuggestion;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.*;

/**
 * @author macos-zyj
 */
@Slf4j
@Component
public  class EsSupportRepository {
    @Resource
    private ElasticsearchRestTemplate restTemplate;
    private static final List<String> SUGGESTION_LIST = Arrays.asList("suggest_text","full_pinyin","prefix_pinyin","like_pinyin");
    private static final String PREFIX_FIELD_NAME = "kwsuggest";

    /**
     * 获取相关搜索，最多返回9条
     * @param searchKey 查询词
     * @return 条件列表
     */
    public List<String> searchSuggest(String searchKey) {
        log.info("elasticsearch 推荐补全查询 查询字段:{}",searchKey);
        SearchResponse response = restTemplate.suggest(initSuggestBuilder(searchKey), SupportEsDO.class);
        Suggest suggest = response.getSuggest();
        if (suggest != null) {
            return analyseSuggest(suggest,searchKey);
        }
        return new ArrayList<>(0);
    }

    /**
     * 尝试根据result书籍根据 加权优化分析算法
     * @param suggest
     * @param searchKey
     * @return
     */
    private List<String> analyseSuggest(Suggest suggest,String searchKey){
        Set<String> resultSet = new LinkedHashSet<>(8);
        int index = 0;
        for(String suggestionType : SUGGESTION_LIST){
            CompletionSuggestion completionSuggestion = suggest.getSuggestion(suggestionType);
            for (CompletionSuggestion.Entry entry : completionSuggestion.getEntries()) {
                for (CompletionSuggestion.Entry.Option option : entry) {
                    String suggestText =  option.getHit().getSourceAsMap().get(PREFIX_FIELD_NAME).toString();
                    resultSet.add(suggestText);
                }
            }
            // 按照中文匹配、全拼匹配、拼音首字母匹配、模糊匹配的顺序，结果大于5的时候返回结果，根据自己业务需要判断这个返回的数量
            if(resultSet.size()>=5){
                break;
            }
            // 中文匹配，全拼匹配以及拼音首字母匹配存在结果的，不需要模糊匹配
            if(index==3 && resultSet.size()>0){
                break;
            }
            // 超过3个字模糊匹配不准确
            if(searchKey.length()>3 && resultSet.size()==0){
                break;
            }
            index++;
        }
        return new ArrayList<>(resultSet);
    }

    /**
     * 尝试通过常量和反射的形式获取对应的fieldName
     * @param searchKey 查询字段
     * @return
     */
    private SuggestBuilder initSuggestBuilder(String searchKey){
        SuggestBuilder suggestBuilder=new SuggestBuilder();
        suggestBuilder.addSuggestion("suggest_text", SuggestBuilders.completionSuggestion("kwsuggest.suggest_text").prefix(searchKey).skipDuplicates(true).size(5));
        suggestBuilder.addSuggestion("full_pinyin", SuggestBuilders.completionSuggestion("kwsuggest.full_pinyin").prefix(searchKey).skipDuplicates(true).size(5));
        suggestBuilder.addSuggestion("prefix_pinyin", SuggestBuilders.completionSuggestion("kwsuggest.prefix_pinyin").prefix(searchKey).skipDuplicates(true).size(5));
        suggestBuilder.addSuggestion("like_pinyin", SuggestBuilders.completionSuggestion("kwsuggest.like_pinyin").prefix(searchKey, Fuzziness.fromEdits(1)).skipDuplicates(true).size(5));
        return suggestBuilder;
    }
}
